package ar.edu.itba.it.cg.grupo01.impl;

import static com.google.common.base.Preconditions.checkArgument;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.vecmath.Point3f;
import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;

public class Utilities {

	/**
	 * Check if a list of points are on the same plane.
	 * @param points
	 * @return
	 */
	public static boolean pointsOnSamePlane (List<Point3f> points) {
				
		// check arguments
		checkArgument(points.size() >= 3, "At least 3 points are needed to define a plane");
		//TODO check point are not the same
		
		
		// calculate plane equation [
		Vector3f dir1 = new Vector3f(points.get(0));
		Vector3f dir2 = new Vector3f(points.get(0));
		dir1.sub(points.get(1));
		dir2.sub(points.get(2));
		
		Vector3f normal = new Vector3f();
		normal.cross(dir1, dir2);
		
		MathPlane plane = new MathPlane(points.get(0), normal);
		
		for (Point3f point : points) {
			if (!plane.contains(point))
				return false;
			
		}

		return true;
	}
	
	/**
	 * Returns a list with the first element as the vertex with the right angle if the points
	 * form a right triangle or null otherwise.
	 * @param a
	 * @param b
	 * @param c
	 * @return
	 */
	public static List<Point3f> pointsFormRightTriangle(Point3f a, Point3f b, Point3f c) {
		
		Vector3f v1 = new Vector3f(a);
		Vector3f v2 = new Vector3f(b);
		Vector3f v3 = new Vector3f(c);
		
		v1.sub(b);
		v2.sub(c);
		v3.sub(a);
		
		List<Point3f> points = new ArrayList<Point3f>();
		if (Math.abs(v1.dot(v2)) < Precision.EPSILON) {
			points.add(b);
			points.add(c);
			points.add(a);
			return points;
		}
		
		if (Math.abs(v2.dot(v3)) < Precision.EPSILON) {
			points.add(c);
			points.add(a);
			points.add(b);
			return points;
		}
		
		if (Math.abs(v3.dot(v1)) < Precision.EPSILON) {
			points.add(a);
			points.add(b);
			points.add(c);
			return points;
		}
		
		return null;
	}
	
	public static Color averageColors(Collection<Color> colors) {
		
		int r = 0;
		int g = 0;
		int b = 0;
		for (Color color : colors) {
			r += color.getRed();
			g += color.getGreen();
			b += color.getBlue();
		}
		
		return new Color(r/colors.size(), g/colors.size(), b/colors.size());
	}

	public static List<Vector2f> subdividePixel(float size, int n) {
		
		List<Vector2f> points = new ArrayList<Vector2f>();
		
		float nnew = (float) Math.pow(2, n);
		float d = size / (float)Math.pow(2, n+1);
		
		for (int i=0; i<nnew; i++) {
			for (int j=0; j<nnew; j++) {
				points.add(new Vector2f(j*2*d + d, i*2*d + d));
			}
		}
		
		return points;
	}
	
	public static void main(String[] args) {
		
		Collection<Vector2f> points = Utilities.subdividePixel(1, 2);
		System.out.println("points = " + points);
		System.out.println("size = " + points.size());
	}
}
